#include "led_sysfs.h"
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <dirent.h>

static int write_text_file(const char *path, const char *text)
{
    FILE *f = fopen(path, "w");
    if (!f) return -1;
    int ok = fputs(text, f) >= 0;
    fclose(f);
    return ok ? 0 : -1;
}

static void led_sysfs_prepare_trigger(const char *brightness_path)
{
    // 尝试将 trigger 置为 none，避免 heartbeat/timer 等触发器覆盖亮度
    // brightness_path: .../leds/<name>/brightness -> derive trigger path
    char trig[512];
    size_t base = strlen(brightness_path) - strlen("brightness");
    if (base < sizeof(trig)) {
        snprintf(trig, sizeof(trig), "%.*strigger", (int)base, brightness_path);
        (void)write_text_file(trig, "none");
    }
}

int led_sysfs_set_brightness_path(const char *brightness_path, int on)
{
    led_sysfs_prepare_trigger(brightness_path);
    // 尝试读取 max_brightness 以判断是否支持 >1 的值
    char maxpath[512];
    snprintf(maxpath, sizeof(maxpath), "%.*smax_brightness",
             (int)strlen(brightness_path) - (int)strlen("brightness"), brightness_path);
    FILE *f = fopen(maxpath, "r");
    int maxv = 1;
    if (f) { if (fscanf(f, "%d", &maxv) != 1) maxv = 1; fclose(f); }
    char buf[32];
    snprintf(buf, sizeof(buf), "%d", on ? (maxv > 1 ? maxv : 1) : 0);
    return write_text_file(brightness_path, buf);
}

int led_sysfs_set(const char *name, int on)
{
    char path[512];
    snprintf(path, sizeof(path), "/sys/class/leds/%s/brightness", name);
    return led_sysfs_set_brightness_path(path, on);
}

int led_sysfs_autodetect(char *out_name, unsigned out_sz)
{
    if (!out_name || out_sz == 0) return -1;
    const char *priority[] = { "led2", "led1", "led3" };
    for (size_t i = 0; i < sizeof(priority)/sizeof(priority[0]); ++i) {
        char p[512]; snprintf(p, sizeof(p), "/sys/class/leds/%s/brightness", priority[i]);
        FILE *f = fopen(p, "r"); if (f) { fclose(f); strncpy(out_name, priority[i], out_sz-1); out_name[out_sz-1]='\0'; return 0; }
    }
    DIR *d = opendir("/sys/class/leds");
    if (!d) return -1;
    struct dirent *e;
    while ((e = readdir(d)) != NULL) {
        if (e->d_name[0] == '.') continue;
        // skip non-directories heuristically; we still try
        strncpy(out_name, e->d_name, out_sz-1); out_name[out_sz-1] = '\0';
        closedir(d);
        return 0;
    }
    closedir(d);
    return -1;
}
